package com.techsoft.executor;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.techsoft.ConnectionPool.DatabaseType;
import com.techsoft.DBException;
import com.techsoft.DataExecutor;

public class DataExecutorFactory {
	private static final Logger Log = LoggerFactory
			.getLogger(DataExecutorFactory.class);
	private static Map<DatabaseType, String> dbclasses = new ConcurrentHashMap<DatabaseType, String>();

	static {
		dbclasses.put(DatabaseType.ORACLE,
				"com.techsoft.executor.OracleExecutor");
		dbclasses
				.put(DatabaseType.MYSQL, "com.techsoft.executor.MysqlExecutor");
		dbclasses.put(DatabaseType.SQLSERVER,
				"com.techsoft.executor.SqlServerExecutor");
		dbclasses.put(DatabaseType.DB2, "com.techsoft.executor.DB2Executor");
	}

	public static DataExecutor getExecutor(DatabaseType databaseType)
			throws DBException {
		String dbclass = dbclasses.get(databaseType);
		if (dbclass == null) {
			Log.error("Not implemented for " + databaseType.name());
			throw new DBException("Not implemented for " + databaseType.name());
		}

		try {
			Class<?> cls = Class.forName(dbclass);
			return (DataExecutor) cls.newInstance();
		} catch (Exception e) {
			Log.error("Can not Create DataExecutor [" + dbclass + "] "
					+ ", error info  \n" + e.getMessage());
			throw new DBException("Can not Create DataExecutor [" + dbclass
					+ "] " + ", error info  \n" + e.getMessage());
		}
	}

	public void registerDatabase(DatabaseType databaseType, String className) {
		if (databaseType != null) {
			dbclasses.put(databaseType, className);
		}
	}

	public void unRegisterDatabase(DatabaseType databaseType) {
		if (databaseType != null) {
			dbclasses.remove(databaseType);
		}

	}

	public Set<DatabaseType> getDatabaseTypes() {
		return dbclasses.keySet();
	}
}
